/* Copyright © 2015 Hein-Pieter van Braam <hp@tmm.cx>
 * This work is free. You can redistribute it and/or modify it under the
 * terms of the Do What The Fuck You Want To Public License, Version 2,
 * as published by Sam Hocevar. See the COPYING file for more details.
 *
 * Text copied from http://www.firthworks.com/roger/cloak/
*/

#include <cstddef>
#include <iostream>
#include <stdexcept>
#include <string>
#include <map>

using namespace std;

class object;

class method {
public:
	method(string val): _val(val) {};
	~method() {};

	bool call() {
		cout << "Method: '" << _val << "'"  << endl;
		return true;
	};
private:
	string _val;
};

class object {
friend class method;
public:
	object() {};
	object(object* parent): _parent(parent) {};
	~object() {
		for(auto i: _methods) {
			delete(i.second);
		}
	};

	bool call_method(string name) {
		try {
			method* method = _methods.at(name);
			return method->call();
		} catch (const out_of_range& e) {
			if(_parent) {
				return _parent->call_method(name);
			} else {
				cout << "No method " << name << endl;
				return false;
			}
		}
	};

	void add_method(string name, method* method) {
		_methods[name] = method;
	};
protected:
	object* _parent = nullptr;
	map<string, method*> _methods;
};

int main() {
	object* o = new object();
	o->call_method("stuff");
	o->add_method("stuff", new method("Stuff"));
	o->call_method("stuff");

	object* p = new object(o);
	p->call_method("stuff");
	delete o;
}
